import ASlib.Trazador;
import ASlib.Hilo;

public class Donald
    {
    public static final String GILITO = "Gilito";
    public static final String[] nombres = {"Jorgito","Jaimito","Juanito"};
    public static final int NSOBRINOS = nombres.length;

    static Tio gilito;
    static Sobrino[] sobrinos = new Sobrino[NSOBRINOS];
    static Cuenta cuenta = new Cuenta();

    public static void main(String[] args)
        {
        Crear_hilos();        
        Lanzar_hilos();
        Esperar_hilos();
        System.out.println("-------------------------");
        System.out.println(cuenta.Saldo());
        }

    private static void Crear_hilos()
        {
        gilito = new Tio(GILITO, 2, cuenta);
        for (int i=0; i<NSOBRINOS; i++)
            sobrinos[i] = new Sobrino(nombres[i],2*i+4,cuenta, i == 0 ? 1 : i);
        }
    private static void Lanzar_hilos()
        {
        gilito.start();
        for (int i=0; i<NSOBRINOS; i++)
            sobrinos[i].start();
        }
    private static void Esperar_hilos()
        {
        gilito.Join();
        System.out.println(gilito.nombre+" ha terminado");
            
        for (int i=0; i<NSOBRINOS; i++)
            {
            sobrinos[i].Join();
            System.out.println(sobrinos[i].nombre+" ha terminado");
            }
        }
    }

class Tio extends Hilo
    {
    private Trazador trazador;
    private Cuenta cuenta;
    public  String nombre;

    public Tio(String nombre,int columna, Cuenta cuenta)
        {
        this.nombre = nombre;
        trazador = new Trazador(columna, nombre);
        this.cuenta = cuenta;
        }    
    public void run ()
        {

        trazador.Print("Soy el tio");
        trazador.Print("Mi id es "+getId());
	while (true)
	    {
		this.Pausa(1000);
	  synchronized(cuenta)
		{
	cuenta.Ingresar(1);
	this.notifyAll();
		}
	    }   
        }
}

class Sobrino extends Hilo
    {
    public String nombre;

    Cuenta cuenta;
    Trazador trazador;
    float cuanto;

    public Sobrino(String nombre, int col, Cuenta cuenta, float cuanto)
    {
        this.nombre = nombre;
        trazador = new Trazador(col,nombre);
        this.cuenta = cuenta;
	this.cuanto = cuanto;
    }    
    public void run ()
        {
	    this.Pausa(1000);
	    trazador.Print("Soy un sobrino");
		trazador.Print("Mi id es "+getId());
	synchronized(this.cuenta)
	    {
		//while para que se vuelva a comprobar antes de salir
		while (cuenta.Saldo() < cuanto) this.Wait(cuenta);
		cuenta.Retirar(cuanto);
	    }
			trazador.Print("Termino");
        }
    }

class Cuenta
    {
    private float	saldo = 0;
    public  float Ingresar (float v) 
        {
        float acc = saldo;
	saldo = acc + v;
	return (saldo);
        }
    public  float Retirar (float v) 
        {
        float acc = saldo;
        saldo = acc-v;
	if (saldo > 0) this.notifyAll();
        return (saldo);
        }
    public float Saldo()    {return (saldo);}
    }
